package com.example.template.core.config;
/*
 * Description:
 * Created by lfywh on 2019/4/2721:24
 */


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.example.template.core.exception.ServiceException;
import com.example.template.core.model.AppJsonMessage;
import com.example.template.core.model.CommonConst;
import org.apache.xmlbeans.impl.xb.xsdschema.All;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.config.annotation.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName WebMvcConfigurer
 * @Description TODO
 * @Date 2019/4/27 21:24
 **/
@Configuration
public class WebMvcConfigurer extends WebMvcConfigurationSupport {
    private final Logger logger = LoggerFactory.getLogger(WebMvcConfigurer.class);

//    @Override
//    protected void addInterceptors(InterceptorRegistry registry) {
//        registry.addInterceptor(new MyTestInterceptor()).addPathPatterns("/**").excludePathPatterns("/index.html");
//        super.addInterceptors(registry);
//    }



    /***
     * @Description //TODO 统一异常处理
     * @MethodName configureHandlerExceptionResolvers
     * @Date 22:32 2019/4/27
     * @Param [exceptionResolvers]
     * @Return void
     **/
    @Override
    protected void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
        exceptionResolvers.add(new HandlerExceptionResolver() {
            @Override
            public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
                AppJsonMessage result = new AppJsonMessage();
                if (e instanceof ServiceException) {
                    result.setCode(CommonConst.FAIL.code).setMsg(e.getMessage());
                    logger.info(e.getMessage());
                } else if (e instanceof NoHandlerFoundException) {
                    result.setCode(CommonConst.NOT_FOUND.code).setMsg(e.getMessage()+":"+httpServletRequest.getRequestURI());
                } else if (e instanceof ServletException) {
                    result.setCode(CommonConst.FAIL.code).setMsg(e.getMessage());
                } else {
                    result.setCode(CommonConst.FAIL.code).setMsg("接口 ["+httpServletRequest.getRequestURI()+"] "+e.getMessage());
                    String message;
                    if (o instanceof HandlerMethod) {
                        HandlerMethod handlerMethod = (HandlerMethod) o;
                        message = String.format("接口 [%s] 出现异常，方法：%s.%s，异常摘要：%s",
                                httpServletRequest.getRequestURI(),
                                handlerMethod.getBean().getClass().getName(),
                                handlerMethod.getMethod().getName(),
                                e.getMessage());
                    } else {
                        message = e.getMessage();
                    }
                    logger.error(message, e);
                }
                responseResult(httpServletResponse, result);
                return new ModelAndView();
            }
        });
    }

    @Override
    protected void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowCredentials(true)
                .allowedHeaders("*")
                .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS", "PATCH");
    }


    private void responseResult(HttpServletResponse response, AppJsonMessage result) {
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-type", "application/json;charset=UTF-8");
        response.setStatus(200);
        try {
            response.getWriter().write(JSON.toJSONString(result));
        } catch (IOException ex) {
            logger.error(ex.getMessage());
        }
    }

    /**
     * 添加静态资源--过滤swagger-api (开源的在线API文档)
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //过滤swagger
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");

        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");

        registry.addResourceHandler("/swagger-resources/**")
                .addResourceLocations("classpath:/META-INF/resources/swagger-resources/");

        registry.addResourceHandler("/swagger/**")
                .addResourceLocations("classpath:/META-INF/resources/swagger*");

        registry.addResourceHandler("/v2/api-docs/**")
                .addResourceLocations("classpath:/META-INF/resources/v2/api-docs/");

        registry.addResourceHandler("/index.html")
                .addResourceLocations("classpath:/static/index.html");
        registry.addResourceHandler("/static/**")
                .addResourceLocations("classpath:/static/static/");

//        registry.addResourceHandler("/css/**")
//                .addResourceLocations("classpath:/static/css/");
//
//        registry.addResourceHandler("/js/**")
//                .addResourceLocations("classpath:/static/js/");
//        registry.addResourceHandler("/img/**")
//                .addResourceLocations("classpath:/static/img/");
//        registry.addResourceHandler("/fonts/**")
//                .addResourceLocations("classpath:/static/fonts/");



//        registry.addResourceHandler("/manifest.json")
//                .addResourceLocations("classpath:/static/manifest.json");

    }


//    @Override
//    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//        //1.需要定义一个convert转换消息的对象;
//        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
//        //2.添加fastJson的配置信息，比如：是否要格式化返回的json数据;
//        FastJsonConfig fastJsonConfig = new FastJsonConfig();
//        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat,
//                SerializerFeature.WriteMapNullValue,
//                SerializerFeature.WriteNullStringAsEmpty,
//                SerializerFeature.DisableCircularReferenceDetect,
//                SerializerFeature.WriteNullListAsEmpty,
//                SerializerFeature.WriteDateUseDateFormat);
//        //3处理中文乱码问题
//        List<MediaType> fastMediaTypes = new ArrayList<>();
//        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
//        //4.在convert中添加配置信息.
//        fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
//        fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
//        //5.将convert添加到converters当中.
//        converters.add(fastJsonHttpMessageConverter);
//    }

    @Override
    protected void addViewControllers(ViewControllerRegistry registry) {

        registry.addViewController("/error/404").setViewName("/error/404");
    }
}

